package com.hxzy.shop.utils;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import sun.misc.BASE64Encoder;

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;


/**
 * 使用：  记住我（手机里面）, 传输一些需要加密数据
 * 不(非)对称加密算法  RSA
 * 不对称加密算法使用两把完全不同但又是完全匹配的一对钥匙—公钥和私钥。
 * 在使用不对称加密算法加密文件时，只有使用匹配的一对公钥和私钥，才能完成对明文的加密和解密过程。
 */
public final class RsaUtils {

    /**
     * 密钥长度 于原文长度对应 以及越长速度越慢(512,1024,2048,4096)
     */
    private final static int KEY_SIZE = 1024;

    /**
     * 随机生成密钥对
     * @throws Exception
     */
    public static Map<Integer, String> genKeyPair() throws Exception {

        // KeyPairGenerator类用于生成公钥和私钥对，基于RSA算法生成对象
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
        // 初始化密钥对生成器
        keyPairGen.initialize(KEY_SIZE, new SecureRandom());
        // 生成一个密钥对，保存在keyPair中
        KeyPair keyPair = keyPairGen.generateKeyPair();
        // 得到私钥
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        // 得到公钥
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();

        String publicKeyString = encryptBASE64(publicKey.getEncoded());
        // 得到私钥字符串
        String privateKeyString = encryptBASE64(privateKey.getEncoded());
        // 将公钥和私钥保存到Map

        Map<Integer, String> keyMap = new HashMap<Integer, String>();
        //0表示公钥
        keyMap.put(0, publicKeyString);
        //1表示私钥
        keyMap.put(1, privateKeyString);
        return keyMap;
    }

    /**
     * 把 byte[] --> String
     * @param key
     * @return
     * @throws Exception
     */
    public static String encryptBASE64(byte[] key) throws Exception {
        return (new BASE64Encoder()).encodeBuffer(key);
    }

    /**
     * 私匙RSA--加密
     */
    public static String priEnc(String value, String privateKey, String publicKey) {
        byte[] strByte = StrUtil.bytes(value, CharsetUtil.CHARSET_UTF_8);
        RSA rsa = new RSA(privateKey, publicKey);
        byte[] bytes = rsa.encrypt(strByte, KeyType.PrivateKey);
        return Base64.getEncoder().encodeToString(bytes);
    }

    /**
     * 公匙RSA--解密
     */
    public static String pubDec(String value, String privateKey, String publicKey) {
        byte[] bytes = Base64.getDecoder().decode(value);
        RSA rsa = new RSA(privateKey, publicKey);
        byte[] decrypt = rsa.decrypt(bytes, KeyType.PublicKey);
        return StrUtil.str(decrypt, CharsetUtil.CHARSET_UTF_8);
    }

    public static void main(String[] args) throws Exception {
//        String x="nE8nI3g8Ndji3SPYs5VA4xJ2YVmi+V1HSPrHedqluEqs+SRNkrWtpEFjAoyZcs6FFtUwjnguA4kb/7P76KPIEBw/sc2okyzTdanJ65qyGTqcYgqvQooPha1sNIBUOrboNaHeK6yY1zKUYknTG6uFgRc8RuUgMNe+gDWD5wZ/0+M=";
//        String y="MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAPi0zPFsIhNe4hScJ8rp656yJS6s4R7hvtLmpRjvbnX6AFlHq6Es6pJMUGlXOvoCpbPTwGWwxBXlPDVweng3UiHdodtjiVCCd4v9ysvntjuJfnbZZdo23suYeXvir9K2q4S2RF9+tfvsGZzN7L2pGeg/1TKB6oAN8CJuRV0pqBGXAgMBAAECgYEA10fhswTwBiZ2unJlO476ptb7uohpIcs02+hMduYijrrF/II+fXic3+BxJo4cffc2qg+clinJwk44rOVdDZyNWRBdODSBFa3XMXRNlY7OWXIIFwsSe28jqC2jr3DX3ad7w0P2Xx3TcK0BkUVfKwhrfd8xmonjVqUs3RIJUwE/wZkCQQD+7GiVpMaITXFc9Nh9BUOcvC8bRYo4kljWemywvKwRQTnssW939mOM1lBs9gMn4T4r66nL+zjK6sdKh0OJoESNAkEA+cGrtd/691JyMdP9C4mKPgsfprnAHNg1irrokG0LmZ3+vavQz615ee1fALzkZLLl6bGmcUnODabRlscyjhtvswJAICUfav9EKZvaV6ZoRhuL0w/HwOCb9VY+7Yyyd/bSm7pl23rkW3QuSWwc6CB9dWHpvRAScS5UkwHX74Xu9kPHYQJBAKSnn9KJ1WSUACEFhv/CL1dz8evy7cqWZ8YMLyJ4IXunA7h7u3APB9TwPv+3iEMzBgwpSHfLloK9hdOHg7bYM60CQQC5gIyOainD9aRnFZQ+u2fPXJhCEp4Idyu7DD0n0v2AqMeY3TDgbtzq3ar6/Dkzvpfv/R4vnDvL7CLmwMrv7MjD";
//        String z="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD4tMzxbCITXuIUnCfK6euesiUurOEe4b7S5qUY7251+gBZR6uhLOqSTFBpVzr6AqWz08BlsMQV5Tw1cHp4N1Ih3aHbY4lQgneL/crL57Y7iX522WXaNt7LmHl74q/StquEtkRffrX77Bmczey9qRnoP9UygeqADfAibkVdKagRlwIDAQAB";
//        System.out.println(pubDec(x,y,z));

        //生成 公钥和私钥
//        Map<Integer, String> integerStringMap = genKeyPair();
//        System.out.println("公钥：");
//        System.out.println(integerStringMap.get(0));
//
//        System.out.println("私钥:");
//        System.out.println(integerStringMap.get(1));

         String publicKey="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDFc3F6xTVfgeCBZtuXyFZmwNZOuybDqtpo5WYVM9DdfJUlLfzgfB8Y7W83PbTB/mQCO2ppHcdklim8yMChG0SPeo1PCsR+2dbKiSI8q2KgW5CTErc6B/FXgwDnRkS0Z2sIKFKQfXSxgZ0ebaTXjLp+wMyZIZAAR4xOmQuLiHa4YwIDAQAB";

         String privateKey="MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMVzcXrFNV+B4IFm25fIVmbA1k67JsOq2mjlZhUz0N18lSUt/OB8Hxjtbzc9tMH+ZAI7amkdx2SWKbzIwKEbRI96jU8KxH7Z1sqJIjyrYqBbkJMStzoH8VeDAOdGRLRnawgoUpB9dLGBnR5tpNeMun7AzJkhkABHjE6ZC4uIdrhjAgMBAAECgYAnYKSLBXVlfLNXWzoEBTIl/+M9hFlwwEwai1VWeST4ZvYfmhJKeraA9Ckv7SB1Z9RuFYddO1EeoEvmmGrCNnvvfwA5vcPfGWgnaqILc4vRo4vROflOSnpJLB1VAnN1Q7E8LtsaA+69s6kJWJFSRCn1n0uWumRWc1w3F92ejuY+cQJBAP2NDFtAe95Ra4fqo+oska6wQKF/AT/m0hJYtymHwugJZVEaS9OBUniRHMV8muGeZxZe/5Hpk4ZKl+wcF7Ys3T0CQQDHW61lF+AXx6MItbv62ZWQDhnXI5x7kBI48S+HZhnS7ddU5ylg9I249iC6tmHGpPgvSBItYbKbhPdFdrX5woYfAkB6bMx2kyA8LFwbeHRE8dg13OyYDdbwn+b27NcjumWl3EOLcYMDUQIdLRQTVyMBpZZo+t2z+nA8+293lejtEaSRAkEArmVpqz0WoVbYLX9lwYzkRI/BVS3m70TaXAvJS0YrIxVDQRezYAivjfVqLkvr/u1D24DNvftwVpIcCh1OFf5wewJBAMxcZzsezljQrROGOLOx3Cznn3n1xgxi6ibq9dmxpdpHbi+S8KOWDER8O3KE7lmUYbSf2HP9RY9gy696zibIJbk=";

         String value="你好呀";

        String encodeValue = priEnc(value, privateKey, publicKey);
        System.out.println("加密后的值");
        System.out.println(encodeValue);

        String pwdValue="EmQelwX+2X1DgSQlVF/ADucWrTFizClP8vJ39f9+c3uEqwaXLGk1/f4kUrNiWeUcqgNUd92yzQrHGkEdYbUmZAGh38fkZ5kpH/0tx3jE8y1pwN+XyF+8d+jCus9jMSox6lQDXNP/A9+Fbjso803xZPR8l1kmoJq5nTP7hDGgyxQ=";

        String decodeValue = pubDec(pwdValue, privateKey, publicKey);
        System.out.println("解密后的值");
        System.out.println(decodeValue);


    }
}
